package com.sc.nft.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sc.nft.dao.EcologyCastExchangeConfDao;
import com.sc.nft.dao.EquityPropsDao;
import com.sc.nft.dao.UserEcologyCastRecordsDetailsDao;
import com.sc.nft.dto.*;
import com.sc.nft.entity.*;
import com.sc.nft.entity.vo.ecology.AdminExchangeCastUpperLimitConfVO;
import com.sc.nft.entity.vo.ecology.ExchangeCastUpperLimitConfVO;
import com.sc.nft.enums.EcologyRewardsType;
import com.sc.nft.enums.UserEcologyCastUpperLimitDetailsTypeEnum;
import com.sc.nft.enums.UserEquityPropsUseTypeEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.UserEcologyCastUpperLimitService;
import com.sc.nft.service.UserEquityPropsService;
import com.sc.nft.sup.ErrorCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.sc.nft.service.EcologyCastExchangeConfService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 生态-铸造上限兑换配置表服务接口实现
 *
 * @author Sun
 * @description 由 Mybatisplus Code Generator 创建
 * @since 2024-06-07 09:03:55
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class EcologyCastExchangeConfServiceImpl implements EcologyCastExchangeConfService {

    private final EcologyCastExchangeConfDao ecologyCastExchangeConfDao;
    private final EcologyCastExpendConfDao ecologyCastExpendConfDao;
    private final EcologyHatchConfDao ecologyHatchConfDao;
    private final EquityPropsDao equityPropsDao;
    private final EcologyCastConfDao ecologyCastConfDao;
    private final EcologyHatchRewardsConfDao ecologyHatchRewardsConfDao;
    private final UserEcologyHatchRecordsDao userEcologyHatchRecordsDao;
    private final UserEcologyCastUpperLimitService userEcologyCastUpperLimitService;
    private final UserEquityPropsService userEquityPropsService;
    private final UserEcologyCastRecordsDetailsDao userEcologyCastRecordsDetailsDao;
    private final UserEcologyCastRecordsDao userEcologyCastRecordsDao;

    @Override
    public void addExchangeCastUpperLimit(EcologyCastExchangeConf ecologyCastExchangeConf) {
        EcologyCastConf ecologyCastConf = ecologyCastConfDao.getById(ecologyCastExchangeConf.getEcologyCastId());
        Assert.notNull(ecologyCastConf, () -> new GlobalRunTimeException("生态铸造配置不存在"));

        EquityProps equityProps = equityPropsDao.getById(ecologyCastExchangeConf.getEquityPropsId());
        Assert.notNull(equityProps, () -> new GlobalRunTimeException("道具卡不存在"));

        Assert.isFalse(ecologyCastExchangeConfDao.getIsExistByEcologyCastIdAndEquityPropsId(ecologyCastConf.getId(), equityProps.getId()), () -> new GlobalRunTimeException("请勿重复配置"));

        ecologyCastExchangeConf.setCollectionId(ecologyCastConf.getCollectionId());
        ecologyCastExchangeConf.setEquityPropsName(equityProps.getFirstTitle());
        ecologyCastExchangeConf.setCollectionName(ecologyCastConf.getCollectionName());
        ecologyCastExchangeConf.insert();
    }

    @Override
    public void dealExchangeCastUpperLimit(Long id) {
        EcologyCastExchangeConf ecologyCastExchangeConf = ecologyCastExchangeConfDao.getById(id);
        Assert.notNull(ecologyCastExchangeConf, () -> new GlobalRunTimeException("兑换配置不存在"));

        Assert.isTrue(ecologyCastExchangeConfDao.dealExchangeCastUpperLimitById(id), () -> new GlobalRunTimeException("删除失败"));
    }

    @Override
    public List<AdminExchangeCastUpperLimitConfVO> getExchangeCastUpperLimitConf(Long ecologyCastId) {
        return ecologyCastExchangeConfDao.getExchangeCastUpperLimitConf(ecologyCastId);
    }

    @Override
    public void updateStatus(Long id, Boolean status) {

        EcologyCastExchangeConf ecologyCastExchangeConf = ecologyCastExchangeConfDao.getById(id);
        Assert.notNull(ecologyCastExchangeConf, () -> new GlobalRunTimeException("兑换配置不存在"));
        Assert.isFalse(ecologyCastExchangeConf.getStatus().equals(status), () -> new GlobalRunTimeException("状态未发生改变"));

        Assert.isTrue(ecologyCastExchangeConfDao.updateStatusById(id, status), () -> new GlobalRunTimeException("更新失败"));
    }

    /**
     * 获取生态铸造上限兑换配置
     *
     * @param ecologyCastId
     * @return
     */
    @Override
    public Boolean getIsExistByEcologyCastId(Long ecologyCastId) {
        return ecologyCastExchangeConfDao.getIsExistByEcologyCastId(ecologyCastId);
    }

    /**
     * 获取生态铸造上限兑换配置
     *
     * @param ecologyCastId
     * @return
     */
    @Override
    public List<ExchangeCastUpperLimitConfVO> getExchangeCastUpperLimitConfList(UserInfo userInfo, Long ecologyCastId) {
        EcologyCastConf ecologyCastConf = ecologyCastConfDao.getById(ecologyCastId);
        Assert.notNull(ecologyCastConf, () -> new GlobalRunTimeException("生态铸造配置不存在"));
        // 获取可兑换数量
        UserEcologyCastUpperLimit userEcologyCastUpperLimit = userEcologyCastUpperLimitService.getOne(userInfo.getId(), ecologyCastConf.getCollectionId());
        Integer canBeExchangedNum =  Objects.isNull(userEcologyCastUpperLimit) ? 0 : userEcologyCastUpperLimit.getExchangeCount();
        List<ExchangeCastUpperLimitConfVO> exchangeCastUpperLimitConfList = ecologyCastExchangeConfDao.getExchangeCastUpperLimitConfList(userInfo.getId(), ecologyCastId);
        for (ExchangeCastUpperLimitConfVO exchangeCastUpperLimitConfVO : exchangeCastUpperLimitConfList) {
            exchangeCastUpperLimitConfVO.setCanBeExchangedNum(canBeExchangedNum);
        }
        return exchangeCastUpperLimitConfList;
    }

    /**
     * 用户兑换铸造上限
     *
     * @param id       兑换配置Id
     * @param count    兑换数量
     * @param userInfo 用户信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void exchange(Long id, Integer count, UserInfo userInfo) {
        EcologyCastExchangeConf ecologyCastExchangeConf = ecologyCastExchangeConfDao.getById(id);
        Assert.notNull(ecologyCastExchangeConf, () -> new GlobalRunTimeException("兑换配置不存在"));
        Assert.isTrue(ecologyCastExchangeConf.getStatus(), () -> new GlobalRunTimeException("兑换配置已关闭"));

        EcologyCastConf ecologyCastConf = ecologyCastConfDao.getById(ecologyCastExchangeConf.getEcologyCastId());
        Assert.notNull(ecologyCastConf, () -> new GlobalRunTimeException("生态铸造配置不存在"));

        EquityProps equityProps = equityPropsDao.getById(ecologyCastExchangeConf.getEquityPropsId());
        Assert.notNull(equityProps, () -> new GlobalRunTimeException("道具卡不存在"));

        // 获取可兑换数量
        UserEcologyCastUpperLimit userEcologyCastUpperLimit = userEcologyCastUpperLimitService.getOne(userInfo.getId(), ecologyCastConf.getCollectionId());
        Integer canBeExchangedNum = Objects.isNull(userEcologyCastUpperLimit) ? 0 : userEcologyCastUpperLimit.getExchangeCount();
        Assert.isTrue(canBeExchangedNum >= count, () -> new GlobalRunTimeException("可兑换次数不足"));
        // 获取用户持有的道具数量
        Integer havingCount = userEquityPropsService.getHavingCountByUserId(ecologyCastExchangeConf.getEquityPropsId(), userInfo.getId());
        Integer sumCount = ecologyCastExchangeConf.getExpendCount() * count;
        Assert.isTrue(havingCount.intValue() >= sumCount.intValue(), () -> new GlobalRunTimeException("所需道具不足"));
        // 获取需要消耗的道具
        List<UserEquityProps> userEquityPropsList = userEquityPropsService.getHavingListByUserIdAndEquityPropsIdAndLimit(userInfo.getId(), ecologyCastExchangeConf.getEquityPropsId(), sumCount);
        //扣除权益商品
        Assert.isTrue(userEquityPropsService.normalToconsumeByIds(userEquityPropsList, userInfo.getId(), "兑换" + ecologyCastExchangeConf.getCollectionName() + "铸造上限",
                id, UserEquityPropsUseTypeEnum.CAP_CONVERTIBILITY), () -> new GlobalRunTimeException(ErrorCode.FAILED_TO_OBTAIN_EQUITY_PROPS));
        // 添加铸造上限
        userEcologyCastUpperLimitService.addCountByUserIdAndCollectionId(userInfo.getId(), ecologyCastConf.getCollectionId(), count, UserEcologyCastUpperLimitDetailsTypeEnum.EXCHANGE,
                ecologyCastExchangeConf.getCollectionName(), 0L);
        Assert.isTrue(
                userEcologyCastUpperLimitService.subExchangeCount(userInfo.getId(), ecologyCastConf.getCollectionId(), count),
                () -> new GlobalRunTimeException("兑换失败,请稍后重试"));

    }

    /**
     * 初始化配置表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void initEcologyWayConf() {
        List<EcologyCastConf> list = ecologyCastConfDao.getAll();
        for (EcologyCastConf ecologyCastConf : list) {
            EcologyCastWayConf ecologyCastWayConf = new EcologyCastWayConf();
            ecologyCastWayConf.setWayName("燃料加生态券");
            ecologyCastWayConf.setEcologyCastConfId(ecologyCastConf.getId());
            ecologyCastWayConf.setStatus(Boolean.TRUE);
            ecologyCastWayConf.insert();
            ecologyCastExpendConfDao.updateWayConfIdByEcologyCastConfId(ecologyCastConf.getId(), ecologyCastWayConf.getId());
            userEcologyCastRecordsDetailsDao.updateWayConfIdByEcologyCastConfId(ecologyCastConf.getId(), ecologyCastWayConf.getId());
            userEcologyCastRecordsDao.updateWayConfIdByEcologyCastConfId(ecologyCastConf.getId(), ecologyCastWayConf.getId());
        }

    }
}